package com.xjgc.common.utils;


import com.xjgc.model.entity.general.ZxjZsdstr009;
import org.apache.commons.collections.ListUtils;
import org.apache.commons.lang.StringUtils;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;


import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Date;
import java.sql.Time;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.*;

import static com.xjgc.common.utils.DateTimeUtils.strToSqlTime;
import static com.xjgc.common.utils.DateTimeUtils.strToSqlDate;

/**
 * 用于设置bean的属性值
 */
public class SetterUtils {

    private Class<?> aClass = null;
    private List<Map<String, String>> strArgs = null;
    private List<Map<String, String>> intArgs = null;
    private List<Map<String, String>> doubleArgs = null;
    private List<Map<String, String>> longArgs = null;
    private List<Map<String, String>> dateArgs = null;
    private List<Map<String, String>> timeArgs = null;
    private List<Object> entities = null;//业务需要的实体bean

    /**
     * 设置类名
     *
     * @param className
     * @throws ClassNotFoundException
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    public void setClass(String className) throws ClassNotFoundException {
        this.aClass = Class.forName(className);
    }

    /**
     * 仅适用于大写的字段
     *
     * @return
     */
    public void setArgs(String xmlData) throws DocumentException {
        Iterator<Element> iterator = DocumentHelper.parseText(xmlData).getRootElement().elementIterator();
        this.strArgs = new ArrayList<>();
        this.intArgs = new ArrayList<>();
        this.doubleArgs = new ArrayList<>();
        this.longArgs = new ArrayList<>();
        this.dateArgs = new ArrayList<>();
        this.timeArgs = new ArrayList<>();
        List<String> sout = null;
        while (iterator.hasNext()) {
            sout = new ArrayList<>();
            HashMap<String, String> strArg = new HashMap<>();
            HashMap<String, String> intArg = new HashMap<>();
            HashMap<String, String> doubleArg = new HashMap<>();
            HashMap<String, String> longArg = new HashMap<>();
            HashMap<String, String> dateArg = new HashMap<>();
            HashMap<String, String> timeArg = new HashMap<>();

            Element next = iterator.next();
            Iterator<Element> iterator1 = next.elementIterator();
            while (iterator1.hasNext()) {
                Element next1 = iterator1.next();
                Method declaredMethod;
                try {
                    declaredMethod = this.aClass.getMethod(getGetter(next1.getName()), null);
                } catch (NoSuchMethodException e) {
                    sout.add("Xml中存在数据库中不包含字段：" + next1.getName() + "\n");
//                    System.out.println("Xml中存在数据库中不包含字段："+next1.getName());
                    continue;
                }
                if (String.class.getName().equals(declaredMethod.getGenericReturnType().getTypeName())) {
                    strArg.put(next1.getName(), next1.getText());
                } else if (Integer.class.getName().equals(declaredMethod.getGenericReturnType().getTypeName())) {
                    intArg.put(next1.getName(), next1.getText());
                } else if (Double.class.getName().equals(declaredMethod.getGenericReturnType().getTypeName())) {
                    doubleArg.put(next1.getName(), next1.getText());
                } else if (Long.class.getName().equals(declaredMethod.getGenericReturnType().getTypeName())) {
                    longArg.put(next1.getName(), next1.getText());
                } else if (Date.class.getName().equals(declaredMethod.getGenericReturnType().getTypeName())) {
                    dateArg.put(next1.getName(), next1.getText());
                } else if (Time.class.getName().equals(declaredMethod.getGenericReturnType().getTypeName())) {
                    timeArg.put(next1.getName(), next1.getText());
                }
            }

            this.strArgs.add(strArg);
            this.intArgs.add(intArg);
            this.doubleArgs.add(doubleArg);
            this.longArgs.add(longArg);
            this.dateArgs.add(dateArg);
            this.timeArgs.add(timeArg);
        }
        if (sout.size() != 0)
            System.out.println(sout.toString());
    }

    public SetterUtils setStrAttributeOfBean(Map<String, String> args, Object newInstance) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        if (this.aClass != null && newInstance != null) {
            Set<Map.Entry<String, String>> entries = args.entrySet();
            for (Map.Entry<String, String> entry : entries) {
                String key = entry.getKey();
                String value = entry.getValue();
                Method setter = aClass.getMethod(getSetter(key), String.class);
                setter.invoke(newInstance, StringUtils.trim(value));
            }
        }
        return this;

    }

    public SetterUtils setIntAttributeOfBean(Map<String, String> args, Object newInstance) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        if (this.aClass != null && newInstance != null) {
            Set<Map.Entry<String, String>> entries = args.entrySet();
            for (Map.Entry<String, String> entry : entries) {
                String key = entry.getKey();
                String value = entry.getValue();
                if (StringUtils.isBlank(value)){
                    continue;
                }
                Method setter = this.aClass.getMethod(getSetter(key), Integer.class);
                setter.invoke(newInstance, Integer.parseInt(value));
            }
        }
        return this;

    }

    public SetterUtils setDoubleAttributeOfBean(Map<String, String> args, Object newInstance) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        if (this.aClass != null && newInstance != null) {
            Set<Map.Entry<String, String>> entries = args.entrySet();
            for (Map.Entry<String, String> entry : entries) {
                String key = entry.getKey();
                String value = entry.getValue();
                if (StringUtils.isBlank(value)){
                    continue;
                }
                Method setter = this.aClass.getMethod(getSetter(key), Double.class);
                setter.invoke(newInstance, Double.parseDouble(value));
            }
        }
        return this;
    }

    public SetterUtils setLongAttributeOfBean(Map<String, String> args, Object newInstance) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        if (this.aClass != null && newInstance != null) {
            Set<Map.Entry<String, String>> entries = args.entrySet();
            for (Map.Entry<String, String> entry : entries) {
                String key = entry.getKey();
                String value = entry.getValue();
                if (StringUtils.isBlank(value)){
                    continue;
                }
                Method setter = this.aClass.getMethod(getSetter(key), Long.class);
                setter.invoke(newInstance, Long.parseLong(value));
            }
        }
        return this;
    }

    public SetterUtils setDateAttributeOfBean(Map<String, String> args, Object newInstance) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, ParseException {
        if (this.aClass != null && newInstance != null) {
            Set<Map.Entry<String, String>> entries = args.entrySet();
            for (Map.Entry<String, String> entry : entries) {
                String key = entry.getKey();
                String value = entry.getValue();
                if (StringUtils.isBlank(value)){
                    continue;
                }
                Method setter = aClass.getMethod(getSetter(key), Date.class);
                setter.invoke(newInstance, strToSqlDate(value));
            }
        }
        return this;
    }

    public SetterUtils setTimeAttributeOfBean(Map<String, String> args, Object newInstance) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        if (this.aClass != null && newInstance != null) {
            Set<Map.Entry<String, String>> entries = args.entrySet();
            for (Map.Entry<String, String> entry : entries) {
                String key = entry.getKey();
                String value = entry.getValue();
                if (StringUtils.isBlank(value)){
                    continue;
                }
                Method setter = aClass.getMethod(getSetter(key), Time.class);
                setter.invoke(newInstance, strToSqlTime(value));
            }
        }
        return this;
    }

    /**
     * 将字符串首字母转为大写，其余字母为小写，得到setter方法
     * 现在仅支持字符串中含有一个下划线，例BSTKD_E
     *
     * @param name
     * @return
     */
    public String getSetter(String name) {
        String res1, res2 = "";
        String[] split = name.split("_");
        res1 = "set" + StringUtils.capitalize(StringUtils.lowerCase(split[0]));
        if (split.length > 1) {
          // res2 = StringUtils.capitalize(StringUtils.lowerCase(split[1]));
            int i=1;
            while (i<split.length) {
                res2 += StringUtils.capitalize(StringUtils.lowerCase(split[i]));
                i++;
            }
        }
        return res1 + res2;

    }

    /**
     * 得到setter方法
     *
     * @param name
     * @return
     */
    public String getGetter(String name) {
        String res1, res2 = "";
        String[] split = name.split("_");
        res1 = "get" + StringUtils.capitalize(StringUtils.lowerCase(split[0]));
        if (split.length > 1) {
            int i=1;
            while (i<split.length) {
                res2+= StringUtils.capitalize(StringUtils.lowerCase(split[i]));
                i++;
            }
        }
        return res1 + res2;

    }

    public List<Object> getInstance() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, ParseException {
        this.entities = new ArrayList<>();
        for (int i = 0; i < this.strArgs.size(); i++) {
            Object instance = aClass.newInstance();
            setStrAttributeOfBean(this.strArgs.get(i), instance)
                    .setIntAttributeOfBean(this.intArgs.get(i), instance)
                    .setDoubleAttributeOfBean(this.doubleArgs.get(i), instance)
                    .setLongAttributeOfBean(this.longArgs.get(i), instance)
                    .setDateAttributeOfBean(this.dateArgs.get(i), instance)
                    .setTimeAttributeOfBean(this.timeArgs.get(i), instance);
            entities.add(instance);
        }

        if (this.entities.size() != 0) {
            return this.entities;
        }

        return ListUtils.EMPTY_LIST;
    }


    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, ParseException, DocumentException {
        String xmlData = "<?xml version=\"1.0\" encoding=\"utf-8\"?><ROOT>" +
                "<item>" +
                "<WERKS>0801</WERKS><VKORG>9208</VKORG><JOBDAT>2019-11-27</JOBDAT><JOBNAME>TEST0002_9208</JOBNAME><INDEX1>28</INDEX1><BSTKD>111123131</BSTKD>" +
                "<KUNNR>1369000010</KUNNR><NAME1>哈尔滨电力局</NAME1><KWMENG_SUM>30.000</KWMENG_SUM><NETWR_SUM>9000.00</NETWR_SUM><ERDAT>2015-05-12</ERDAT>" +
                "<VDATU>2015-05-12</VDATU><AEDAT>0000-00-00</AEDAT><KWMENG>30.000</KWMENG><NETPR>300.00</NETPR><JE>9000.00</JE><VBELN>4000009004</VBELN>" +
                "<POSNR>001000</POSNR><TCSJ>0000-00-00</TCSJ><CJRQ>0000-00-00</CJRQ><GGRQ>0000-00-00</GGRQ><ZZTCSJ>0000-00-00</ZZTCSJ><ARKTX>DDZY1001-Z 单相智能电表东软</ARKTX>" +
                "<ERDAT1>2015-05-12</ERDAT1><NAME2>黑龙江电工仪器仪表工程研究中心有限公司工厂</NAME2><MATNR>000000000720010101</MATNR><MEINS>套</MEINS><EDATU>2015-05-12</EDATU>" +
                "<LFSTA>B</LFSTA><CHARG_AU>000000</CHARG_AU><GMNGA>0.000</GMNGA><PCJE>9000.00</PCJE><MODIFIED>0000-00-00</MODIFIED><DATA01_1>0000-00-00</DATA01_1>" +
                "<DATA01_2>0000-00-00</DATA01_2><DATA01_9>0000-00-00</DATA01_9><DATA02_1>0000-00-00</DATA02_1><DATA02_2>0000-00-00</DATA02_2><DATA02_9>0000-00-00</DATA02_9>" +
                "<DATA03_1>0000-00-00</DATA03_1><DATA03_2>0000-00-00</DATA03_2><DATA03_3>0000-00-00</DATA03_3><DATA03_5>0000-00-00</DATA03_5><DATA03_9>0000-00-00</DATA03_9>" +
                "<DATA04_1>0000-00-00</DATA04_1><DATA04_2>0000-00-00</DATA04_2><DATA04_9>0000-00-00</DATA04_9><DATA05_3>0000-00-00</DATA05_3><DATA05_4>0000-00-00</DATA05_4>" +
                "<DATA05_9>0000-00-00</DATA05_9><DATA06_1>0000-00-00</DATA06_1><DATA06_3>0000-00-00</DATA06_3><DATA06_4>0000-00-00</DATA06_4><DATA06_9>0000-00-00</DATA06_9>" +
                "<DATA07_3>0000-00-00</DATA07_3><DATA07_4>0000-00-00</DATA07_4><DATA07_9>0000-00-00</DATA07_9><DATA08_1>0000-00-00</DATA08_1><DATA08_2>0000-00-00</DATA08_2>" +
                "<DATA08_9>0000-00-00</DATA08_9><DATA09_1>0000-00-00</DATA09_1><DATA09_2>0000-00-00</DATA09_2><DATA09_9>0000-00-00</DATA09_9><DATA12_1>0000-00-00</DATA12_1>" +
                "<DATA12_2>0000-00-00</DATA12_2><DATA12_9>0000-00-00</DATA12_9><DATA13_0>0000-00-00</DATA13_0><DATA13_5>0000-00-00</DATA13_5><DATA14_1>0000-00-00</DATA14_1>" +
                "<DATA14_2>2019-10-02</DATA14_2><DATA15_1>0000-00-00</DATA15_1><DATA15_2>0000-00-00</DATA15_2><DATA15_3>0000-00-00</DATA15_3><DATA16_1>0000-00-00</DATA16_1>" +
                "<DATA16_2>2019-10-20</DATA16_2><DATUM>2019-11-27</DATUM><UZEIT>16:35:17</UZEIT></item><item><WERKS>0801</WERKS><VKORG>9208</VKORG><JOBDAT>2019-11-27</JOBDAT>" +
                "<JOBNAME>TEST0002_9208</JOBNAME><INDEX1>30</INDEX1><BSTKD>123</BSTKD><KUNNR>1369000010</KUNNR><NAME1>哈尔滨电力局</NAME1><KWMENG_SUM>1000.000</KWMENG_SUM>" +
                "<NETWR_SUM>200000.00</NETWR_SUM><ERDAT>2015-05-13</ERDAT><VDATU>2015-05-14</VDATU><AEDAT>0000-00-00</AEDAT><KWMENG>1000.000</KWMENG><NETPR>200.00</NETPR>" +
                "<JE>200000.00</JE><VBELN>4000009026</VBELN><POSNR>001000</POSNR><TCSJ>0000-00-00</TCSJ><CJRQ>0000-00-00</CJRQ><GGRQ>0000-00-00</GGRQ><ZZTCSJ>0000-00-00</ZZTCSJ>" +
                "<ARKTX>DDZY1001-Z 单相智能电表东软</ARKTX><ERDAT1>2015-05-13</ERDAT1><NAME2>黑龙江电工仪器仪表工程研究中心有限公司工厂</NAME2><MATNR>000000000720010101</MATNR>" +
                "<MEINS>套</MEINS><EDATU>2015-05-14</EDATU><LFSTA>A</LFSTA><CHARG_AU>000000</CHARG_AU><GMNGA>0.000</GMNGA><PCJE>200000.00</PCJE><MODIFIED>0000-00-00</MODIFIED>" +
                "<DATA01_1>0000-00-00</DATA01_1><DATA01_2>0000-00-00</DATA01_2><DATA01_9>0000-00-00</DATA01_9><DATA02_1>0000-00-00</DATA02_1><DATA02_2>0000-00-00</DATA02_2>" +
                "<DATA02_9>0000-00-00</DATA02_9><DATA03_1>0000-00-00</DATA03_1><DATA03_2>0000-00-00</DATA03_2><DATA03_3>0000-00-00</DATA03_3><DATA03_5>0000-00-00</DATA03_5>" +
                "<DATA03_9>0000-00-00</DATA03_9><DATA04_1>0000-00-00</DATA04_1><DATA04_2>0000-00-00</DATA04_2><DATA04_9>0000-00-00</DATA04_9><DATA05_3>0000-00-00</DATA05_3>" +
                "<DATA05_4>0000-00-00</DATA05_4><DATA05_9>0000-00-00</DATA05_9><DATA06_1>0000-00-00</DATA06_1><DATA06_3>0000-00-00</DATA06_3><DATA06_4>0000-00-00</DATA06_4>" +
                "<DATA06_9>0000-00-00</DATA06_9><DATA07_3>0000-00-00</DATA07_3><DATA07_4>0000-00-00</DATA07_4><DATA07_9>0000-00-00</DATA07_9><DATA08_1>0000-00-00</DATA08_1>" +
                "<DATA08_2>0000-00-00</DATA08_2><DATA08_9>0000-00-00</DATA08_9><DATA09_1>0000-00-00</DATA09_1><DATA09_2>0000-00-00</DATA09_2><DATA09_9>0000-00-00</DATA09_9>" +
                "<DATA12_1>0000-00-00</DATA12_1><DATA12_2>0000-00-00</DATA12_2><DATA12_9>0000-00-00</DATA12_9><DATA13_0>0000-00-00</DATA13_0><DATA13_5>0000-00-00</DATA13_5>" +
                "<DATA14_1>0000-00-00</DATA14_1><DATA14_2>0000-00-00</DATA14_2><DATA15_1>0000-00-00</DATA15_1><DATA15_2>0000-00-00</DATA15_2><DATA15_3>0000-00-00</DATA15_3>" +
                "<DATA16_1>0000-00-00</DATA16_1><DATA16_2>0000-00-00</DATA16_2><DATUM>2019-11-27</DATUM><UZEIT>16:35:17</UZEIT>" +
                "</item>" +
                "</ROOT>";

        SetterUtils setterUtils = new SetterUtils();
        setterUtils.setClass("com.xjgc.model.entity.general.ZxjZsdstr009");
        setterUtils.setArgs(xmlData);
        List<Object> enObjects = setterUtils.getInstance();
        System.out.println("--------------");
        for (Object o : enObjects) {
            ZxjZsdstr009 zxjZsdstr009 = (ZxjZsdstr009) o;
            System.out.println(zxjZsdstr009.getUzeit());
        }

    }

}
